﻿using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using System.Text.RegularExpressions;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using WMPLib;

 
namespace WebSiteUpdateChecker
{
    public partial class MainForm : Form
    {
        /// <summary>更新チェック間隔。</summary>
        private TimeSpan timeSpan;
        /// <summary>前回更新チェック時間。</summary>
        private DateTime prevTime;
        /// <summary>Windows Media Player。</summary>
        private WindowsMediaPlayer mediaPlayer;

        #region 初期化・終了処理

        /// <summary>
        /// コンストラクタ。
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            try
            {
                // DB接続
                webPageDataSet.OpenConnection();

                // 設定
                webPageDataSet.Settings.CreateDataAdapter();
                webPageDataSet.Settings.FillTable();

                // ページ
                webPageDataSet.WebPage.CreateDataAdapter();
                webPageDataSet.WebPage.FillTable();
            }
            catch (Exception)
            {
                MessageBox.Show("データベースの読み込みに失敗しました。", Application.ProductName);
            }

            // サイクル間隔初期化
            timeSpan = new TimeSpan(0, 0, (int)Properties.Settings.Default.CycleTime);
            prevTime = DateTime.Now;
            cycleTimer.Start();
            
            // メディアプレイヤー初期化
            mediaPlayer = new WindowsMediaPlayer();
        }



        /// <summary>
        /// フォーム読込みイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            // ウィンドウ
            this.Icon = Icon.FromHandle(Properties.Resources.MainIcon.GetHicon());
            this.Name = Application.ProductName;

            // ウィンドウ状態
            this.WindowState = Properties.Settings.Default.WindowState;
            this.Bounds = new Rectangle(
                this.Location = Properties.Settings.Default.WindowLocation,
                this.Size = Properties.Settings.Default.WindowSize);

            // 通知領域
            this.mainNotifyIcon.Icon = Icon.FromHandle(Properties.Resources.MainIcon.GetHicon());
            this.mainNotifyIcon.Text = Application.ProductName;

            webPageDataGridView.ClearSelection();
        }

        /// <summary>
        /// フォームを閉じる前のイベント。
        /// Windows終了時以外は確認メッセージを表示する。
        /// ウィンドウ状態を保存する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                DialogResult result = MessageBox.Show(
                    "アプリケーションを終了しますか？",
                    Application.ProductName,
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question);

                if (result != DialogResult.Yes)
                    e.Cancel = true;
            }

            // ウィンドウ状態はバインディングが上手くいかないのでここで設定
            Properties.Settings.Default.WindowState = this.WindowState;
            if (this.WindowState == FormWindowState.Normal)
            {
                Properties.Settings.Default.WindowLocation = this.Location;
                Properties.Settings.Default.WindowSize = this.Size;
            }
            else
            {
                Properties.Settings.Default.WindowLocation = this.RestoreBounds.Location;
                Properties.Settings.Default.WindowSize = this.RestoreBounds.Size;
            }
        }

        /// <summary>
        /// フォームを閉じた後のイベント。
        /// 設定を保存する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                webPageDataSet.WebPage.UpdateTable(); // ページ情報を書き込む
                webPageDataSet.Settings.UpdateTable(); // 設定を書き込む。
                webPageDataSet.CloseConnection();
            }
            catch
            {
                MessageBox.Show(
                    "Webページ一覧の書き込みに失敗しました。" + Environment.NewLine + "変更した設定値は保存されません。",
                    Application.ProductName);
            }
        }

        /// <summary>
        /// ウィンドウリサイズイベント。
        /// 最小化した際にフォームを非表示にする。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void MainForm_Resize(object sender, EventArgs e)
        {
            //ResizeBegin
            //--ドラッグ中繰返し↓-----
            //Resize
            //SizeChanged
            //ClientSizeChanged
            //--ドラッグ中繰返し↑-----
            //ResizeEnd

            if (this.WindowState == FormWindowState.Minimized)
            {
                //フォームを非表示にする
                this.Visible = false;
            }
        }

        /// <summary>
        /// タスクトレイアイコンのダブルクリックイベント。
        /// ウィンドウを表示する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void mainNotifyIcon_DoubleClick(object sender, EventArgs e)
        {
            this.Visible = true;
            if (this.WindowState == FormWindowState.Minimized)
                this.WindowState = FormWindowState.Normal;
            this.Activate();
        }

        /// <summary>
        /// ウィンドウアクティブイベント。
        /// タスクトレイアイコンを通常に戻す。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void MainForm_Activated(object sender, EventArgs e)
        {
            mainNotifyIcon.Icon = Icon.FromHandle(Properties.Resources.MainIcon.GetHicon());
        }

        #endregion



        #region ページ更新処理

        /// <summary>
        /// サイクルタイマーイベント。
        /// 更新確認を行う。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void cycleTimer_Tick(object sender, EventArgs e)
        {
            TimeSpan span = DateTime.Now - prevTime; // 前回チェック時との時間差
            double spanSeconds = (timeSpan - span).TotalSeconds;
            timerCounterToolStripStatusLabel.Text = "次のチェックまで " + (spanSeconds >= 0 ? spanSeconds.ToString("0") : "0") + "秒";
            if (spanSeconds > 0) return; // サイクル時間以内の場合は無効

            // 更新確認
            checkStatusToolStripStatusLabel.Text = "ページを確認しています...";
            Application.DoEvents();
            int count = CheckPage();

            if (count == 0)
            {
                checkStatusToolStripStatusLabel.Text = "[" + DateTime.Now + "] 更新はありませんでした";
            }
            else
            {
                checkStatusToolStripStatusLabel.Text = "[" + DateTime.Now + "] " + count + "件の更新がありました";
            }
            UpdateSiteInformation();

            prevTime = DateTime.Now; // サイクル時間リセット
        }


        /// <summary>
        /// ページの更新を確認する。
        /// </summary>
        private int CheckPage()
        {
            int count = 0;
            string diffText = "";
            string subject = "";

            // 全ての行の文字色を黒で初期化
            foreach (DataGridViewRow r in webPageDataGridView.Rows)
            {
                r.DefaultCellStyle.ForeColor = Color.Black;
            }

            // 更新確認
            WebPageDataSet.WebPageDataTable table = webPageDataSet.WebPage;
            Parallel.For(0, table.Count, index =>
            {
                if (table[index].CheckLatestPage())
                {
                    // 本文
                    string info =
                        "[" + table[index].Title + "]" + Environment.NewLine +
                        "URL：" + table[index].Url + Environment.NewLine +
                        "検出日時：" + table[index].LatestTime + Environment.NewLine +
                        "更新内容：" + Environment.NewLine +
                        "========================================" + Environment.NewLine +
                        Environment.NewLine +
                        table[index].LatestDiff + Environment.NewLine;
                    diffText += info;
                    // 件名
                    subject += Environment.NewLine + "[" + table[index].Title + "]";

                    // 変更があった場合に該当行の文字色を赤にする
                    foreach (DataGridViewRow r in webPageDataGridView.Rows)
                    {
                        if (((DataRowView)r.DataBoundItem).Row == table[index])
                        {
                            r.DefaultCellStyle.ForeColor = Color.Red;
                            break;
                        }
                    }

                    count++;
                }
            });
            Application.DoEvents();

            // 更新無しなら終了
            if (count == 0) return 0;

            // サウンド通知
            if (Properties.Settings.Default.InformSound)
            {
                mediaPlayer.controls.stop();
                mediaPlayer.URL = Properties.Settings.Default.InformSoundPath;
                mediaPlayer.settings.volume = 100;
                mediaPlayer.controls.play();

                // 再生可能な状態になるまで待機
                while (mediaPlayer.openState == WMPOpenState.wmposOpeningUnknownURL && mediaPlayer.playState == WMPPlayState.wmppsTransitioning)
                {
                    System.Threading.Thread.Sleep(10);
                    Application.DoEvents();
                }

                // 再生に失敗した場合
                if (mediaPlayer.openState != WMPOpenState.wmposMediaOpen || mediaPlayer.currentMedia.getItemInfo("MediaType") != "audio")
                {
                    mediaPlayer.controls.stop();
                    System.Media.SystemSounds.Asterisk.Play(); // アラート音を再生する
                }
                else
                {
                    informSoundStopToolStripSplitButton.Visible = true; // 再生停止ボタンを表示
                    Application.DoEvents();
                }
            }

            // アイコン通知
            if (Properties.Settings.Default.InformIcon)
            {
                mainNotifyIcon.Icon = Icon.FromHandle(Properties.Resources.MainIcon_Inform.GetHicon());
            }

            // バルーン通知
            if (Properties.Settings.Default.InformBalloon)
            {
                mainNotifyIcon.BalloonTipTitle = "ページが更新されました"; // タイトル
                mainNotifyIcon.BalloonTipText = subject; // 表示内容
                mainNotifyIcon.BalloonTipIcon = ToolTipIcon.Info; // アイコン
                mainNotifyIcon.ShowBalloonTip(10000); // 表示時間(ミリ秒)
            }

            // メール通知
            if (Properties.Settings.Default.InformMail)
            {
                // 文字コード
                Encoding enc = Encoding.GetEncoding("iso-2022-jp");

                //GMail Initialize
                SmtpClient smtp = new SmtpClient();
                smtp.Host = Properties.Settings.Default.SenderServer;
                smtp.Port = (int)Properties.Settings.Default.SenderServerPort;
                //SSL
                smtp.EnableSsl = true;

                //GMail認証
                smtp.Credentials = new System.Net.NetworkCredential(
                    Properties.Settings.Default.SenderUser,
                    Properties.Settings.Default.SenderPassword);

                MailMessage mail = new MailMessage(
                    Properties.Settings.Default.SenderMail,
                    Properties.Settings.Default.RecipientMail);
                
                // 件名
                mail.Subject = EncodeMailHeader("ページ更新通知" + subject.Replace(Environment.NewLine, " "), enc);

                // 本文
                AlternateView altView = AlternateView.CreateAlternateViewFromString(
                     diffText, enc, System.Net.Mime.MediaTypeNames.Text.Plain);
                altView.TransferEncoding = System.Net.Mime.TransferEncoding.SevenBit;
                mail.AlternateViews.Add(altView);

                //メール送信
                smtp.Send(mail);

                webPageDataSet.WebPage.UpdateTable();
            }

            return count;
        }


        /// <summary>
        /// メッセージヘッダのためのRFC2047形式の文字列に変換する（Base64）
        /// </summary>
        /// <param name="str">変換もとの文字列</param>
        /// <param name="enc">エンコーディング</param>
        /// <returns></returns>
        private string EncodeMailHeader(string str, Encoding enc)
        {
            //Base64でエンコードする
            string base64str = Convert.ToBase64String(enc.GetBytes(str));
            //RFC2047形式に
            base64str = string.Format("=?{0}?B?{1}?=", enc.BodyName, base64str);
            return base64str;
        }

        #endregion



        #region Webページ情報

        /// <summary>
        /// 「追加」ボタンクリックイベント。
        /// Webページデータを追加する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void addButton_Click(object sender, EventArgs e)
        {
            if (siteUrlTextBox.Text == "" || siteTitleTextBox.Text == "")
            {
                MessageBox.Show("URLとタイトルを入力してください。");
                return;
            }
            try
            {
                WebPageDataSet.GetPageHtml(new Uri(siteUrlTextBox.Text));
            }
            catch
            {
                MessageBox.Show("URLが無効です。");
                return;
            }

            try
            {
                WebPageDataSet.WebPageRow page = webPageDataSet.WebPage.NewWebPageRow();

                page.SetUrl(siteUrlTextBox.Text);
                page.Title = siteTitleTextBox.Text;
                page.FilterStart = siteFilterIncludeTextBox.Text;
                page.FilterEnd = siteFilterEndTextBox.Text;
                page.FilterInclude = siteFilterIncludeTextBox.Text;
                page.FilterIgnore = siteFilterIgnoreTextBox.Text;
                page.Comment = siteCommentTextBox.Text;
                page.Status = siteStatusEnabledRadioButton.Checked;

                page.CheckedTime = DateTime.MinValue;
                page.LatestTime = DateTime.MinValue;
                page.LatestHtml = "";
                page.LatestDiff = "";

                webPageDataSet.WebPage.Rows.Add(page);

                // データベースを更新
                webPageDataSet.WebPage.UpdateTable();
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    "データの追加に失敗しました。" + Environment.NewLine + Environment.NewLine + ex.Message,
                    Application.ProductName,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }
         }

        /// <summary>
        /// 「更新」ボタンクリックイベント。
        /// Webページデータを更新する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void modifyButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (webPageDataGridView.SelectedRows == null || webPageDataGridView.SelectedRows.Count == 0)
                {
                    MessageBox.Show("更新対象をリストから選択してください。。");
                    return;
                }
                if (siteUrlTextBox.Text == "" || siteTitleTextBox.Text == "")
                {
                    MessageBox.Show("URLとタイトルを入力してください。");
                    return;
                }
                try
                {
                    WebPageDataSet.GetPageHtml(new Uri(siteUrlTextBox.Text));
                }
                catch
                {
                    MessageBox.Show("URLが無効です。");
                    return;
                }

                WebPageDataSet.WebPageRow page =
                    (WebPageDataSet.WebPageRow)((DataRowView)webPageDataGridView.SelectedRows[0].DataBoundItem).Row;

                page.SetUrl(siteUrlTextBox.Text);
                page.Title = siteTitleTextBox.Text;
                page.FilterStart = siteFilterStartTextBox.Text;
                page.FilterEnd = siteFilterEndTextBox.Text;
                page.FilterInclude = siteFilterIncludeTextBox.Text;
                page.FilterIgnore = siteFilterIgnoreTextBox.Text;
                page.Comment = siteCommentTextBox.Text;
                page.Status = siteStatusEnabledRadioButton.Checked;

                // データベースを更新
                webPageDataSet.WebPage.UpdateTable();
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    "データの更新に失敗しました。" + Environment.NewLine + Environment.NewLine + ex.Message,
                    Application.ProductName,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// 「削除」ボタンクリックイベント。
        /// Webページデータを削除する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void deleteButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (webPageDataGridView.SelectedRows == null || webPageDataGridView.SelectedRows.Count == 0)
                {
                    MessageBox.Show("削除対象をリストから選択してください。。");
                    return;
                }

                WebPageDataSet.WebPageRow page =
                    (WebPageDataSet.WebPageRow)((DataRowView)webPageDataGridView.SelectedRows[0].DataBoundItem).Row;
                page.Delete();

                // データベースを更新
                webPageDataSet.WebPage.UpdateTable();

            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    "データの削除に失敗しました。" + Environment.NewLine + Environment.NewLine + ex.Message,
                    Application.ProductName,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }
            
        }

        /// <summary>
        /// 「URL」クリックイベント。
        /// 入力したURLを開く。無効の場合は何もしない。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void siteUrlLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            try
            {
                WebPageDataSet.GetPageHtml(new Uri(siteUrlTextBox.Text));
                System.Diagnostics.Process.Start(siteUrlTextBox.Text);
            }
            catch
            {
                MessageBox.Show("URLが無効のため、開くことができませんでした。");
            }
        }

        /// <summary>
        /// タイトル取得ボタンのクリックイベント。
        /// Webページのタイトルを取得する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void webPageTitleGetButton_Click(object sender, EventArgs e)
        {
            try
            {
                // ページ取得
                string page = WebPageDataSet.GetPageHtml(new Uri(siteUrlTextBox.Text));
                if (page == null) throw new ApplicationException();

                Regex regexp = new Regex("<title[^>]*>(.*?)</title>",
                    RegexOptions.IgnoreCase | RegexOptions.Singleline);
                Match match = regexp.Match(page);

                // HTMLデコードしてタイトルを取得
                siteTitleTextBox.Text = WebUtility.HtmlDecode(match.Groups[1].Value.Trim());
            }
            catch (Exception)
            {
                MessageBox.Show("URLが無効のため、タイトルが取得できませんでした。");
            }
        }

        #endregion



        #region メニューイベント

        /// <summary>
        /// メニュー「ファイル」>「インポート」クリックイベント。
        /// XML形式のWebページデータをインポートする。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void fileImportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog ofd = new OpenFileDialog()
                {
                    DefaultExt = "xml",
                    Filter = "XMLファイル(*.xml)|*.xml|すべてのファイル(*.*)|*.*",
                    Multiselect = false,
                };

                if (ofd.ShowDialog() != DialogResult.OK) return;

                webPageDataSet.WebPage.ReadXml(ofd.FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    "データの読み込みに失敗しました。" + Environment.NewLine + Environment.NewLine + ex.Message,
                    Application.ProductName,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// メニュー「ファイル」>「エクスポート」クリックイベント。
        /// WebページデータをXML形式でエクスポートする。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void fileExportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog sfd = new SaveFileDialog()
                {
                    DefaultExt = "xml",
                    Filter = "XMLファイル(*.xml)|*.xml|すべてのファイル(*.*)|*.*",
                };

                if (sfd.ShowDialog() != DialogResult.OK) return;

                webPageDataSet.WebPage.WriteXml(sfd.FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    "データの書き込みに失敗しました。" + Environment.NewLine + Environment.NewLine + ex.Message,
                    Application.ProductName,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// メニュー「ファイル」>「終了」クリックイベント。
        /// フォームを終了する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void fileExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// メニュー「ツール」>「オプション」クリックイベント。
        /// オプションフォームを表示する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void toolOptionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OptionForm optionForm = new OptionForm();

            if (optionForm.ShowDialog() != DialogResult.OK)
                return;

            if (timeSpan.Seconds != (int)Properties.Settings.Default.CycleTime)
                timeSpan = new TimeSpan(0, 0, (int)Properties.Settings.Default.CycleTime);
        }

        /// <summary>
        /// メニュー「ツール」>「更新チェック」クリックイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void toolUpdateCheckToolStripMenuItem_Click(object sender, EventArgs e)
        {
            prevTime = DateTime.Now - timeSpan;
        }

        /// <summary>
        /// メニュー「ツール」>「サウンド停止」クリックイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void toolStopSoundToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mediaPlayer.controls.stop();
            informSoundStopToolStripSplitButton.Visible = false;
        }

        /// <summary>
        /// メニュー「ヘルプ」>「バージョン」クリックイベント。
        /// アプリケーションのバージョン情報を表示する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void helpVersionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(
                this,
                "Web Site Update Checker" + Environment.NewLine
                + "Ver. " + System.Reflection.Assembly.GetEntryAssembly().GetName().Version,
                Application.ProductName,
                MessageBoxButtons.OK,
                MessageBoxIcon.Information);
        }

        #endregion



        #region Webページリスト

        /// <summary>
        /// サイト情報を更新する。
        /// </summary>
        private void UpdateSiteInformation()
        {
            try
            {
                // 選択セルを表示
                WebPageDataSet.WebPageRow page =
                    (WebPageDataSet.WebPageRow)((DataRowView)webPageDataGridView.SelectedRows[0].DataBoundItem).Row;

                siteUrlTextBox.Text = page.Url;
                siteTitleTextBox.Text = page.Title;
                siteFilterStartTextBox.Text = page.FilterStart;
                siteFilterEndTextBox.Text = page.FilterEnd;
                siteFilterIncludeTextBox.Text = page.FilterInclude;
                siteFilterIgnoreTextBox.Text = page.FilterIgnore;
                siteCommentTextBox.Text = page.Comment;
                siteStatusEnabledRadioButton.Checked = page.Status;
                siteStatusDisabledRadioButton.Checked = !page.Status;

                if (page.CheckedTime != DateTime.MinValue)
                    siteCheckedDateTextBox.Text = page.CheckedTime.ToString();
                else
                    siteCheckedDateTextBox.Text = "";

                if (page.LatestTime != DateTime.MinValue)
                    siteLatestDateTextBox.Text = page.LatestTime.ToString();
                else
                    siteLatestDateTextBox.Text = "";
            }
            catch
            {
                // 選択状態クリア
                webPageDataGridView.ClearSelection();
                siteTitleTextBox.Text = "";
                siteUrlTextBox.Text = "";
                siteFilterStartTextBox.Text = "";
                siteFilterEndTextBox.Text = "";
                siteFilterIncludeTextBox.Text = "";
                siteFilterIgnoreTextBox.Text = "";
                siteCommentTextBox.Text = "";
                siteStatusEnabledRadioButton.Checked = true;
                siteStatusDisabledRadioButton.Checked = false;

                siteCheckedDateTextBox.Text = "";
                siteLatestDateTextBox.Text = "";
            }
        }

        /// <summary>
        /// 選択行変更イベント。
        /// Webページ情報を更新する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void webPageDataGridView_SelectionChanged(object sender, EventArgs e)
        {
            UpdateSiteInformation();
        }

        /// <summary>
        /// リストクリックイベント。
        /// リストの余白をクリックした場合、選択を解除する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void webPageDataGridView_MouseClick(object sender, MouseEventArgs e)
        {
            // リストの余白をクリックした場合は選択解除
            if (webPageDataGridView.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.None)
                webPageDataGridView.ClearSelection();
        }

        /// <summary>
        /// データテーブル変更イベント。
        /// 更新日時が変更された場合、表示色を変える。
        /// 変更をサイト情報に反映する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void webPageDataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            // 更新日時が変更された場合、
            if (e.RowIndex >= 0 && e.ColumnIndex > 0)
            {
                if (e.ColumnIndex == 2)
                    webPageDataGridView.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Red;
                else
                    webPageDataGridView.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Black;
            }

            UpdateSiteInformation();
        }

        /// <summary>
        /// データテーブル内チェックボックス変更イベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void webPageDataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            // チェックボックスの変更をコミットする
            if (webPageDataGridView.CurrentCellAddress.X == 0 && webPageDataGridView.IsCurrentCellDirty)
            {
                webPageDataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
            }
        }

        #endregion





    }
}
